/**
 * @Project Name:cn.hoofungson.studio
 * @Package Name:cn.hoofungson.sso.service.common
 * @Since JDK 1.8
 */
package cn.hoofungson.sso.service.common;

import cn.hoofungson.sso.config.Constant;
import io.jsonwebtoken.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @Description: Jwt业务实现
 * @Author 胡松 hoofungson@163.com
 * @Date 2017-11-10 21:14
 * @Version V1.0
 */
@Service
public class JwtServiceImpl implements JwtService {

    @Value("${spring.profiles.active}")
    private String profiles;

    /**
     * 由字符串生成加密key
     *
     * @return
     */
    @Override
    public SecretKey generalKey() {
        String stringKey = profiles + Constant.JWT_SECRET;
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 创建jwt
     *
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     * @throws Exception
     */
    @Override
    public String createJWT(String id, String subject, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey key = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                .signWith(signatureAlgorithm, key);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 解密jwt
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    @Override
    public Claims parseJWT(String jwt) {
        SecretKey key = generalKey();
        Claims claims = Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(jwt).getBody();
        return claims;
    }

    /**
     * 验证jwt
     *
     * @param jwt
     * @return
     **/
    @Override
    public Boolean validateJWT(String jwt) {
        Claims claims = null;
        try {
            claims = parseJWT(jwt);
        } catch (SignatureException e){
            return false;
        } catch (MalformedJwtException e){
            return false;
        } catch (ExpiredJwtException e){
            return false;
        }
        return claims != null?true:false;
    }
}
